home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / xwindows / demos / xfract_1.z / xfract_1 / xfractint-1.06 / lsys.c < prev    next >
C/C++ Source or Header  |  1992-09-28  |  21KB  |  895 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #ifdef __TURBOC__
  6. #include <alloc.h>
  7. #else
  8. #include <malloc.h>
  9. #endif
  10. #include "fractint.h"
  11. #include "prototyp.h"
  12.  
  13. #define size    ssize
  14. /* Needed for use of asm -- helps decide which pointer to function
  15.  * to put into the struct lsys_cmds.
  16.  */
  17. extern int cpu;
  18. extern int fpu;
  19. extern int debugflag;
  20. extern int xdots,ydots;
  21. extern int colors;
  22. extern char LFileName[];
  23. extern char LName[];
  24. extern double param[];
  25. extern int overflow;
  26.  
  27. struct lsys_cmd {
  28.   char ch;
  29.   void (*f)(long n);
  30.   long n;
  31. };
  32.  
  33. static double      _fastcall getnumber(char far **);
  34. static struct lsys_cmd far * _fastcall findsize(struct lsys_cmd far *,struct lsys_cmd far **,int);
  35. static int      _fastcall findscale(struct lsys_cmd far *, struct lsys_cmd far **, int);
  36. static struct lsys_cmd far * _fastcall drawLSys(struct lsys_cmd far *, struct lsys_cmd far **, int);
  37. static int      _fastcall readLSystemFile(char *);
  38. static void      _fastcall free_rules_mem(void);
  39. static int      _fastcall save_rule(char *,char far **);
  40. static struct lsys_cmd far *SizeTransform(char far *s);
  41. static struct lsys_cmd far *DrawTransform(char far *s);
  42. static void free_lcmds();
  43.  
  44. static long aspect; /* aspect ratio of each pixel, ysize/xsize */
  45.  
  46. /* Some notes to Adrian from PB, made when I integrated with v15:
  47.      printfs changed to work with new user interface
  48.      bug at end of readLSystemFile, the line which said rulind=0 fixed
  49.        to say *rulind=0
  50.      the calloc was not worthwhile, it was just for a 54 byte area, cheaper
  51.        to keep it as a static;    but there was a static 201 char buffer I
  52.        changed to not be static
  53.      use of strdup was a nono, caused problems running out of space cause
  54.        the memory allocated each time was never freed; I've changed to
  55.        use far memory and to free when done
  56.    */
  57.  
  58. long sins[50];
  59. long coss[50];
  60. /* dmaxangle is maxangle - 1. */
  61. char maxangle,dmaxangle,curcolor;
  62. long size;
  63. unsigned long realangle;
  64. long xpos,ypos;
  65. char counter,angle,reverse,stackoflow;
  66. long lsys_Xmin, lsys_Xmax, lsys_Ymin, lsys_Ymax;
  67.  
  68. /* Macro to take an FP number and turn it into a
  69.  * 16/16-bit fixed-point number.
  70.  */
  71. #define FIXEDMUL    524288L
  72. #define FIXEDPT(x)    ((long) (FIXEDMUL * (x)))
  73.  
  74. /* The number by which to multiply sines, cosines and other
  75.  * values with magnitudes less than or equal to 1.
  76.  * sins and coss are a 3/29 bit fixed-point scheme (so the
  77.  * range is +/- 2, with good accuracy.    The range is to
  78.  * avoid overflowing when the aspect ratio is taken into
  79.  * account.
  80.  */
  81. #define FIXEDLT1    536870912.0
  82.  
  83. /* Multiply by this number to convert an unsigned 32-bit long
  84.  * to an angle from 0-2PI.
  85.  */
  86. #define ANGLE2DOUBLE    (2*PI / 4294967296.)
  87.  
  88. static int ispow2(long n)
  89. {
  90.   return (n == (n & -n));
  91. }
  92.  
  93.  
  94. #ifdef XFRACT
  95. static void lsys_doplus(long n)
  96. {
  97.   if (reverse) {
  98.     if (++angle == maxangle)
  99.       angle = 0;
  100.   }
  101.   else {
  102.     if (angle)
  103.       angle--;
  104.     else
  105.       angle = dmaxangle;
  106.   }
  107. }
  108. #endif
  109.  
  110.  
  111. #ifdef XFRACT
  112. /* This is the same as lsys_doplus, except maxangle is a power of 2. */
  113. static void lsys_doplus_pow2(long n)
  114. {
  115.   if (reverse) {
  116.     angle++;
  117.     angle &= dmaxangle;
  118.   }
  119.   else {
  120.     angle--;
  121.     angle &= dmaxangle;
  122.   }
  123. }
  124. #endif
  125.  
  126.  
  127. #ifdef XFRACT
  128. static void lsys_dominus(long n)
  129. {
  130.   if (reverse) {
  131.     if (angle)
  132.       angle--;
  133.     else
  134.       angle = dmaxangle;
  135.   }
  136.   else {
  137.     if (++angle == maxangle)
  138.       angle = 0;
  139.   }
  140. }
  141. #endif
  142.  
  143.  
  144. #ifdef XFRACT
  145. static void lsys_dominus_pow2(long n)
  146. {
  147.   if (reverse) {
  148.     angle--;
  149.     angle &= dmaxangle;
  150.   }
  151.   else {
  152.     angle++;
  153.     angle &= dmaxangle;
  154.   }
  155. }
  156. #endif
  157.  
  158. static void lsys_doslash(long n)
  159. {
  160.   if (reverse)
  161.     realangle -= n;
  162.   else
  163.     realangle += n;
  164. }
  165. #ifdef XFRACT
  166. #define lsys_doslash_386 lsys_doslash
  167. #endif
  168.  
  169. static void lsys_dobslash(long n)
  170. {
  171.   if (reverse)
  172.     realangle += n;
  173.   else
  174.     realangle -= n;
  175. }
  176.  
  177. #ifdef XFRACT
  178. #define lsys_dobslash_386 lsys_dobslash
  179. #endif
  180.  
  181. static void lsys_doat(long n)
  182. {
  183.   size = multiply(size, n, 19);
  184. }
  185.  
  186. #ifdef XFRACT
  187. #define lsys_doat_386 lsys_doat
  188. #endif
  189.  
  190. static void lsys_dopipe(long n)
  191. {
  192.   angle += maxangle / 2;
  193.   angle %= maxangle;
  194. }
  195.  
  196.  
  197. #ifdef XFRACT
  198. static void lsys_dopipe_pow2(long n)
  199. {
  200.   angle += maxangle >> 1;
  201.   angle &= dmaxangle;
  202. }
  203. #endif
  204.  
  205.  
  206. #ifdef XFRACT
  207. static void lsys_dobang(long n)
  208. {
  209.   reverse = ! reverse;
  210. }
  211. #endif
  212.  
  213. static void lsys_dosizedm(long n)
  214. {
  215.   double angle = (double) realangle * ANGLE2DOUBLE;
  216.   double s, c;
  217.   long fixedsin, fixedcos;
  218.   FPUsincos(&angle, &s, &c);
  219.   fixedsin = (long) (s * FIXEDLT1);
  220.   fixedcos = (long) (c * FIXEDLT1);
  221.  
  222.   xpos += multiply(multiply(size, aspect, 19), fixedcos, 29);
  223.   ypos += multiply(size, fixedsin, 29);
  224.  
  225. /* xpos+=size*aspect*cos(realangle*PI/180);  */
  226. /* ypos+=size*sin(realangle*PI/180);         */
  227.   if (xpos>lsys_Xmax) lsys_Xmax=xpos;
  228.   if (ypos>lsys_Ymax) lsys_Ymax=ypos;
  229.   if (xpos<lsys_Xmin) lsys_Xmin=xpos;
  230.   if (ypos<lsys_Ymin) lsys_Ymin=ypos;
  231. }
  232.  
  233. static void lsys_dosizegf(long n)
  234. {
  235.   xpos += multiply(size, (long) coss[angle], 29);
  236.   ypos += multiply(size, (long) sins[angle], 29);
  237. /* xpos+=size*coss[angle];                   */
  238. /* ypos+=size*sins[angle];                   */
  239.   if (xpos>lsys_Xmax) lsys_Xmax=xpos;
  240.   if (ypos>lsys_Ymax) lsys_Ymax=ypos;
  241.   if (xpos<lsys_Xmin) lsys_Xmin=xpos;
  242.   if (ypos<lsys_Ymin) lsys_Ymin=ypos;
  243. }
  244.  
  245. #ifdef XFRACT
  246. #define lsys_dosizegf_386 lsys_dosizegf
  247. #endif
  248.  
  249. static void lsys_dodrawd(long n)
  250. {
  251.   double angle = (double) realangle * ANGLE2DOUBLE;
  252.   double s, c;
  253.   long fixedsin, fixedcos;
  254.   int lastx, lasty;
  255.   FPUsincos(&angle, &s, &c);
  256.   fixedsin = (long) (s * FIXEDLT1);
  257.   fixedcos = (long) (c * FIXEDLT1);
  258.  
  259.   lastx=(int) (xpos >> 19);
  260.   lasty=(int) (ypos >> 19);
  261.   xpos += multiply(multiply(size, aspect, 19), fixedcos, 29);
  262.   ypos += multiply(size, fixedsin, 29);
  263. /* xpos+=size*aspect*cos(realangle*PI/180);   */
  264. /* ypos+=size*sin(realangle*PI/180);          */
  265.   draw_line(lastx,lasty,(int)(xpos >> 19),(int)(ypos>>19),curcolor);
  266. }
  267.  
  268. static void lsys_dodrawm(long n)
  269. {
  270.   double angle = (double) realangle * ANGLE2DOUBLE;
  271.   double s, c;
  272.   long fixedsin, fixedcos;
  273.   FPUsincos(&angle, &s, &c);
  274.   fixedsin = (long) (s * FIXEDLT1);
  275.   fixedcos = (long) (c * FIXEDLT1);
  276.  
  277. /* xpos+=size*aspect*cos(realangle*PI/180);   */
  278. /* ypos+=size*sin(realangle*PI/180);          */
  279.   xpos += multiply(multiply(size, aspect, 19), fixedcos, 29);
  280.   ypos += multiply(size, fixedsin, 29);
  281. }
  282.  
  283. static void lsys_dodrawg(long n)
  284. {
  285.   xpos += multiply(size, (long) coss[angle], 29);
  286.   ypos += multiply(size, (long) sins[angle], 29);
  287. /* xpos+=size*coss[angle];                    */
  288. /* ypos+=size*sins[angle];                    */
  289. }
  290.  
  291. #ifdef XFRACT
  292. #define  lsys_dodrawg_386 lsys_dodrawg
  293. #endif
  294.  
  295. static void lsys_dodrawf(long n)
  296. {
  297.   int lastx = (int) (xpos >> 19);
  298.   int lasty = (int) (ypos >> 19);
  299.   xpos += multiply(size, (long) coss[angle], 29);
  300.   ypos += multiply(size, (long) sins[angle], 29);
  301. /* xpos+=size*coss[angle];                    */
  302. /* ypos+=size*sins[angle];                    */
  303.   draw_line(lastx,lasty,(int)(xpos>>19),(int)(ypos>>19),curcolor);
  304. }
  305.  
  306. static void lsys_dodrawc(long n)
  307. {
  308.   curcolor = ((int) n) % colors;
  309. }
  310.  
  311. static void lsys_dodrawgt(long n)
  312. {
  313.   curcolor -= n;
  314.   if ((curcolor &= colors-1) == 0)
  315.     curcolor = colors-1;
  316. }
  317.  
  318. static void lsys_dodrawlt(long n)
  319. {
  320.   curcolor += n;
  321.   if ((curcolor &= colors-1) == 0)
  322.     curcolor = 1;
  323. }
  324.  
  325. static double _fastcall getnumber(char far **str)
  326. {
  327.    char numstr[30];
  328.    float ret;
  329.    int i,root,inverse;
  330.  
  331.    root=0;
  332.    inverse=0;
  333.    strcpy(numstr,"");
  334.    (*str)++;
  335.    switch (**str)
  336.    {
  337.    case 'q':
  338.       root=1;
  339.       (*str)++;
  340.       break;
  341.    case 'i':
  342.       inverse=1;
  343.       (*str)++;
  344.       break;
  345.    }
  346.    switch (**str)
  347.    {
  348.    case 'q':
  349.       root=1;
  350.       (*str)++;
  351.       break;
  352.    case 'i':
  353.       inverse=1;
  354.       (*str)++;
  355.       break;
  356.    }
  357.    i=0;
  358.    while (**str<='9' && **str>='0' || **str=='.')
  359.    {
  360.       numstr[i++]= **str;
  361.       (*str)++;
  362.    }
  363.    (*str)--;
  364.    numstr[i]=0;
  365.    ret=atof(numstr);
  366.    if (root)
  367.      ret=sqrt(ret);
  368.    if (inverse)
  369.      ret = 1/ret;
  370.    return ret;
  371. }
  372.  
  373. static struct lsys_cmd far * _fastcall findsize(struct lsys_cmd far *command, struct lsys_cmd far **rules, int depth)
  374. {
  375.    struct lsys_cmd far **rulind;
  376.    int tran;
  377.  
  378. i